﻿/// <reference name="MicrosoftAjax.js"/>
/// <reference path="~/Clients/Scripts/url.debug.js"/>

Type.registerNamespace("GreeNova");

GreeNova.QueryParam = function(name, value) {
    /// <param name="name" type="String" optional="false" mayBeNull="false" />
    /// <param name="value" type="String" optional="false" mayBeNull="true" />
    /// <returns type="GreeNova.QueryParam" />
    this._name;
    this._nameLowerCase;
    this._value;

    this._setName(name);
    this._setValue(value);
};

GreeNova.QueryParam.prototype = {
    get_name: function() {
        ///	<returns type="String" mayBeNull="false"/>
        return this._name;
    },
    get_nameLowerCase: function() {
        ///	<returns type="String" mayBeNull="false"/>
        return this._nameLowerCase;
    },
    get_value: function() {
        ///	<returns type="String" mayBeNull="true"/>
        return this._value;
    },

    _setName: function(name) {
        /// <param name="name" type="String" optional="false" mayBeNull="false" />
        this._name = name;
        this._nameLowerCase = name.toLowerCase();
    },
    _setValue: function(value) {
        /// <param name="value" type="String" optional="false" mayBeNull="true" />
        this._value = value;
    }
};
GreeNova.QueryParam.registerClass('GreeNova.QueryParam', null);



GreeNova.QueryParamCollection = function() {
    this._values = [];
};

GreeNova.QueryParamCollection.prototype = {
    clear: function() {
        this._values.length = 0;
        //this._values = [];
    },

    length: function() {
        ///	<returns type="Number" integer="true"></returns>
        return this._values.length;
    },

    atIndex: function(index) {
        /// <param name="index" type="Number" integer="true" optional="false" mayBeNull="false" />
        ///	<returns type="GreeNova.QueryParam" />
        return this._values[index];
    },

    isQuery: function(name) {
        /// <param name="name" type="String" optional="false" mayBeNull="false" />
        ///	<returns type="Boolean" />
        if (name) {
            var nameLowerCase = name.toLowerCase();
            for (var i in this._values) {
                var q = this._values[i];
                if (q.get_nameLowerCase() === nameLowerCase)
                    return true;
            }
        }
        return false;
    },

    getQuery: function(name) {
        /// <param name="name" type="String" optional="false" mayBeNull="false" />
        ///	<returns type="String" />
        if (name) {
            var nameLowerCase = name.toLowerCase();
            for (var i in this._values) {
                var q = this._values[i];
                if (q.get_nameLowerCase() === nameLowerCase)
                    return q.get_value();
            }
        }
        return undefined;
    },

    setQuery: function(name, value) {
        /// <param name="name" type="String" optional="false" mayBeNull="false" />
        /// <param name="value" type="String" optional="false" mayBeNull="true" />
        if (name) {
            var nameLowerCase = name.toLowerCase();
            for (var i in this._values) {
                var q = this._values[i];
                if (q.get_nameLowerCase() === nameLowerCase) {
                    q._setName(name);
                    q._setValue(value);
                    return;
                }
            }
            this._values.push(new GreeNova.QueryParam(name, value));
        }
    },

    remQuery: function(name) {
        /// <param name="name" type="String" optional="false" mayBeNull="false" />
        if (name) {
            name = name.toLowerCase();
            for (var i in this._values) {
                var q = this._values[i];
                if (q.get_nameLowerCase() === name) {
                    this._values.splice(i, 1);
                    return;
                }
            }
        }
    }
};
GreeNova.QueryParamCollection.registerClass('GreeNova.QueryParamCollection', null);



GreeNova.QueryObject = function(loadCurrentUrl) {
    /// <param name="loadCurrentUrl" type="Boolean" optional="true" mayBeNull="true" />
    this._completeUrl = "";
    this._url = "";
    this._queries;
    this._anchor;
    this._aqueries;

    if (loadCurrentUrl)
        this.loadCurrentUrl();
};

GreeNova.QueryObject.prototype = {
    getCurrentUrl: function() {
        ///	<returns type="String" />
        return window.location.href;
    },

    navigateToUrl: function(url) {
        /// <param name="url" type="String" optional="false" mayBeNull="false" />
        if (window.location.href !== url)
            window.location.href = url;
    },

    _parseQuery: function(query) {
        /// <param name="query" type="String" optional="false" mayBeNull="false" />
        ///	<returns type="GreeNova.QueryParamCollection" />
        var isNamePart = true;
        var name = new Sys.StringBuilder();
        var value = new Sys.StringBuilder();

        var res = new GreeNova.QueryParamCollection();

        for (var i = 0; i < query.length; i++) {
            var ch = query.charAt(i);
            if (ch === "=")
                isNamePart = false;
            else if (ch === "&") {
                if (!name.isEmpty())
                    res.setQuery(name.toString(), value.toString());
                isNamePart = true;
                name.clear();
                value.clear();
            }
            else {
                if (isNamePart)
                    name.append(ch);
                else
                    value.append(ch);
            }
        }
        if (!name.isEmpty())
            res.setQuery(name.toString(), value.toString());
        return res;
    },

    loadUrl: function(url) {
        /// <param name="url" type="String" optional="false" mayBeNull="false" />
        this._anchor = "";

        this._completeUrl = url;
        var pq = this._completeUrl.indexOf('?');
        var pa = this._completeUrl.indexOf('#', pq + 1);
        var paq = this._completeUrl.indexOf('?', pa + 1);

        var query = '';
        var aquery = '';

        this._url = this._completeUrl.substring(0, pq !== -1 ? pq : this._completeUrl.length);
        if (pq !== -1)
            query = this._completeUrl.substring(pq + 1, pa != -1 ? pa : this._completeUrl.length);
        if (pa !== -1) {
            this._anchor = this._completeUrl.substring(pa + 1, paq != -1 ? paq : this._completeUrl.length);
            if (paq !== -1)
                aquery = this._completeUrl.substring(paq + 1);
        }
        this._queries = this._parseQuery(query);
        this._aqueries = this._parseQuery(aquery);
    },

    loadCurrentUrl: function() {
        this.loadUrl(this.getCurrentUrl());
    },

    toString: function() {
        ///	<returns type="String" />
        var url = new Sys.StringBuilder(this._url);

        for (var i = 0; i < this._queries.length(); i++) {
            var q = this._queries.atIndex(i);
            url.append(i === 0 ? "?" : "&");
            url.append(GreeNova.Url.encode(q.get_name()));
            var val = q.get_value();
            if (val) {
                url.append('=');
                url.append(GreeNova.Url.encode(val));
            }
        }
        if (this._aqueries.length() > 0) {
            url.append('#');
            url.append(this._anchor);
            for (var i = 0; i < this._aqueries.length(); i++) {
                var q = this._aqueries.atIndex(i);
                url.append(i === 0 ? "?" : "&");
                url.append(GreeNova.Url.encode(q.get_name()));
                var val = q.get_value();
                if (val) {
                    url.append('=');
                    url.append(GreeNova.Url.encode(val));
                }
            }
        }
        return url.toString();
    },

    navigateTo: function() {
        this.navigateToUrl(this.toString());
    },

    get_url: function() {
        ///	<returns type="String" />
        return this._url;
    },
    set_url: function(value) {
        this._url = value;
    },

    get_anchor: function() {
        ///	<returns type="String" />
        return this._anchor;
    },
    set_anchor: function(value) {
        this._anchor = value;
    },

    get_queries: function() {
        ///<value type="GreeNova.QueryParamCollection"></value>
        return this._queries;
    },

    get_aqueries: function() {
        ///<value type="GreeNova.QueryParamCollection"></value>
        return this._aqueries;
    }
};
GreeNova.QueryObject.registerClass('GreeNova.QueryObject', null);

(function($) {
    $.urlQuery = new function() {
        this.current = function() {
            ///	<returns type="GreeNova.QueryObject" />
            var qo = new GreeNova.QueryObject(true);
            return qo;
        }
    };
})(jQuery);
